import axios from 'axios'
import {
	MessageBox,
	Message,
	Loading
} from 'element-ui'
import store from '@/store'
import {
	getToken
} from '@/utils/cookie.js'
/**
 * 使用了 lodash 的 debounce 防抖。因为有时会碰到在一次请求完毕后又立刻又发起一个新的请求的情况（比如删除一个表格条目后立刻进行刷新）。
 * 这种情况会造成连续 loading 两次，并且中间有一次极短的闪烁。通过防抖可以让 300ms 间隔内的 loading 便合并为一次，避免闪烁的情况。
 */
import _ from 'lodash';
let needLoadingRequestCount = 0;
let loading;
//显示loading
function showLoading(target) {
	// 后面这个判断很重要，因为关闭时加了抖动，此时loading对象可能还存在，
	// 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
	if (needLoadingRequestCount === 0 && !loading) {
		loading = Loading.service({
			lock: true,
			text: "Loading...",
			background: 'rgba(255, 255, 255, 0.5)',
			target: target || "body"
		});
	}
	needLoadingRequestCount++;
}

//隐藏loading
function hideLoading() {
	needLoadingRequestCount--;
	needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); //做个保护
	if (needLoadingRequestCount === 0) {
		//关闭loading
		toHideLoading();
	}
}

//防抖：将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时， loading闪烁的问题。
var toHideLoading = _.debounce(() => {
	loading.close();
	loading = null;
}, 300);
/**
 * axios封装
 */
const service = axios.create({
	/**
	 *访问的基本路径 
	 */
	baseURL: process.env.VUE_APP_BASE_API,
	/**
	 * 超时时间
	 */
	timeout: 5000, // request timeout
})

/**
 * 请求配置
 */
service.interceptors.request.use(
	config => {
		/**
		 * 请求中增加token信息
		 */
		if (config.headers.showLoading !== false) {
			showLoading(config.headers.loadingTarget);
		}
		if (store.getters.token) {
			config.headers['Authorization'] = getToken()
		}
		return config
	},
	error => {
		if (config.headers.showLoading !== false) {
			hideLoading();
		}
		console.log(error) // for debug
		return Promise.reject(error)
	}
)

// 相应配置
service.interceptors.response.use(
	/**
	 * http状态为200
	 */
	response => {
		if (response.config.headers.showLoading !== false) {
			hideLoading();
		}
		const res = response.data
		/**
		 * 如果状态不是是200 请求失败 获取错误信息
		 */
		if (res.code !== 200) {
			Message({
				message: res.msg || 'Error',
				type: 'error',
				duration: 5 * 1000
			})

			/**
			 * token失效
			 */
			if (res.code === 10007) {
				// to re-login
				MessageBox.confirm('登录超时请重新登录',
					'重新登录', {
						confirmButtonText: '重新登录',
						showCancelButton: false,
						closeOnClickModal: false,
						closeOnPressEscape: false,
						closeOnHashChange: false,
						showClose: false,
						type: 'warning'
					}).then(() => {
					/**
					 * 重新获取token
					 */
					store.dispatch('user/resetToken').then(() => {
						location.reload()
					})
				})
			}
			return Promise.reject(new Error(res.msg || 'Error'))
		} else {
			return res
		}
	},
	/**
	 * http状态不是200
	 */
	error => {
		if (error.config.headers.showLoading !== false) {
			hideLoading();
		}
		console.log('err' + error) // for debug
		Message({
			message: error,
			type: 'error',
			duration: 5 * 1000
		})
		return Promise.reject(error)
	}
)

export default service
